import { getToken, removeToken } from '@/utils/auth'
import axios from 'axios'
import { message } from 'ant-design-vue'

message.config({ maxCount: 1 })
// 客户端弹框
const $alert = (msg: string) => {
  // 服务端无游览器端的localStorage，Window
  message.error(msg || '服务器异常')
}
const ResultEnumFail = [-1, -2, -3, -4, -5]
let num = 0
let service: any = {}

// 发布订阅
class EventEmitter {
  private event: any
  constructor() {
    this.event = {}
  }
  on(type, cbres, cbrej) {
    if (!this.event[type]) {
      this.event[type] = [[cbres, cbrej]]
    } else {
      this.event[type].push([cbres, cbrej])
    }
  }

  emit(type, res, ansType) {
    if (!this.event[type]) return
    else {
      this.event[type].forEach((cbArr) => {
        if (ansType === 'resolve') {
          cbArr[0](res)
        } else {
          cbArr[1](res)
        }
      })
    }
  }
}

// 根据请求生成对应的key
function generateReqKey(config, hash) {
  const { method, url, params, data } = config
  return [method, url, JSON.stringify(params), JSON.stringify(data), hash].join('&')
}

// 存储已发送但未响应的请求
const pendingRequest = new Set()
// 发布订阅容器
const ev = new EventEmitter()

;(function creatServer() {
  service = axios.create({
    timeout: 60000,
    headers: {
      'Content-Type': 'application/json',
      reqSource: 'backend'
      // "Access-Control-Allow-Origin": "*",
      // "Access-Control-Allow-Methods": "GET, POST",
    },
    baseURL: 'http://127.0.0.1:3000',
    withCredentials: true
  })

  // 请求拦截器
  service.interceptors.request.use(
    async (config: any) => {
      let hash = location.hash
      // 生成请求Key
      let reqKey = generateReqKey(config, hash)

      if (pendingRequest.has(reqKey)) {
        // 如果是相同请求,在这里将请求挂起，通过发布订阅来为该请求返回结果
        // 这里需注意，拿到结果后，无论成功与否，都需要return Promise.reject()来中断这次请求，否则请求会正常发送至服务器
        let res = null
        try {
          // 接口成功响应
          res = await new Promise((resolve, reject) => {
            ev.on(reqKey, resolve, reject)
          })

          let pendingRes = Promise.reject({
            type: 'limiteResSuccess',
            val: res
          })
          console.log('pendingRes', pendingRes)
          return pendingRes
        } catch (limitFunErr) {
          // 接口报错
          return Promise.reject({
            type: 'limiteResError',
            val: limitFunErr
          })
        }
      } else {
        // 将请求的key保存在config
        config.pendKey = reqKey
        pendingRequest.add(reqKey)
      }

      console.log('111111111111')

      let token = getToken()
      config.headers.congraeduToken = token
      return config
    },
    (error: any) => {
      return Promise.reject(error)
    }
  )

  // 响应拦截器
  service.interceptors.response.use(
    (response: any) => {
      console.log('response', response)
      // 将拿到的结果发布给其他相同的接口
      handleSuccessResponse_limit(response)
      if (response.status === 200) {
        let { data } = response
        let { code, message } = data
        const backEndUrl = import.meta.env.VITE_BACKEND_URL // 你的接口地址

        if (code === 1) {
          return data
        } else if (ResultEnumFail.includes(code)) {
          $alert('登录失效')
          removeToken()
          setTimeout(() => {
            location.href = backEndUrl
          }, 1000)
        } else {
          $alert(message)

          return data
        }
      } else {
        $alert('服务器异常')
        return Promise.reject(response)
      }
    },
    (error: any) => {
      $alert('服务器异常')
      return handleErrorResponse_limit(error)
    }
  )
})()

// 接口响应成功
function handleSuccessResponse_limit(response) {
  const reqKey = response.config.pendKey
  if (pendingRequest.has(reqKey)) {
    let x = null
    try {
      x = JSON.parse(JSON.stringify(response))
    } catch (e) {
      x = response
    }
    pendingRequest.delete(reqKey)
    ev.emit(reqKey, x, 'resolve')
    delete ev.reqKey
  }
}

// 接口走失败响应
function handleErrorResponse_limit(error) {
  if (error.type && error.type === 'limiteResSuccess') {
    return Promise.resolve(error.val)
  } else if (error.type && error.type === 'limiteResError') {
    return Promise.reject(error.val)
  } else {
    const reqKey = error.config.pendKey
    if (pendingRequest.has(reqKey)) {
      let x = null
      try {
        x = JSON.parse(JSON.stringify(error))
      } catch (e) {
        x = error
      }
      pendingRequest.delete(reqKey)
      ev.emit(reqKey, x, 'reject')
      delete ev.reqKey
    }
  }
  return Promise.reject(error)
}

// 请求
const fetch = (url: string, customOptions?: any): Promise<any> => {
  // const reqUrl = import.meta.env.VITE_API_HOST + url; // 你的接口地址
  const reqUrl = url // 你的接口地址
  // const reqUrl = 'http://127.0.0.1:8084' + url // 你的接口地址

  return service(reqUrl, customOptions)
}

class HttpRequest {
  // public _baseUrl

  // constructor(){
  //   const reqUrl = import.meta.env.VITE_API_HOST; // 你的接口地址

  //   this._baseUrl = baseUrl;
  // }
  get(url: string, params?: any): Promise<any> {
    return fetch(url, { method: 'get', params })
  }

  post(url: string, body?: any): Promise<any> {
    return fetch(url, { method: 'post', data: body })
  }

  put(url: string, body?: any): Promise<any> {
    return fetch(url, { method: 'put', body })
  }

  delete(url: string, body?: any): Promise<any> {
    return fetch(url, { method: 'delete', body })
  }

  request(url: any, request = {}) {
    return fetch(url, {
      ...request
    })
  }
}

export default new HttpRequest()
